using System;
using System.Collections.Generic;
using System.Text;
using Decav.Data;
using System.Xml.Serialization;
using System.Xml;

namespace Decav.Reality
{
    /// <summary>
    /// Represents the physical address of a location.
    /// </summary>
    [Serializable]  
    public class StreetAddress : IXmlSerializable
    {
        public StreetAddress()
        {
        }

        public StreetAddress(string address1, string address2, string city,
            string region, string postalcode, Country country, string county)
        {
            _address1 = address1;
            _address2 = address2;
            _city = city;
            Region = region;
            _postalCode = postalcode;
            _country = country;
            _county = county;
        }

        protected StreetAddress(DataRecordAdapter adapt)
        {
            _address1 = adapt.GetString("Address1");
            
            if (adapt.HasValue("Address2"))
                _address2 = adapt.GetString("Address2");

            if (adapt.HasValue("Apartment"))
                _apartment = adapt.GetString("Apartment");

            if (adapt.HasValue("Region"))
                _region = adapt.GetString("Region");
            else if (adapt.HasValue("State"))
                _region = adapt.GetString("State");

            _postalCode = adapt.GetString("PostalCode");

            if (adapt.HasValue("Country"))
                _country = Country.FromCountryCode(adapt.GetString("Country"));
    
            _city = adapt.GetString("City");
        }

        protected StreetAddress(XmlReader reader)
        {
            ((IXmlSerializable)this).ReadXml(reader);
        }

        private string _address1;

        private string _address2;

        private string _region;

        private string _postalCode;

        private Country _country;

        private string _county;

        private string _city;

        private string _apartment;

        /// <summary>
        /// Gets or sets the apartment number or suite name.
        /// </summary>
        public string Apartment
        {
            get
            {
                return _apartment;
            }
            set
            {
                _apartment = value;
            }
        }

        /// <summary>
        /// Gets or sets the first line of the address.
        /// </summary>
        public string Address1
        {
            get
            {
                return _address1;
            }
            set
            {
                _address1 = value;
            }
        }

        /// <summary>
        /// Gets or sets the second line of the address.
        /// </summary>
        public string Address2
        {
            get
            {
                return _address2;
            }
            set
            {
                _address2 = value;
            }
        }

        /// <summary>
        /// Gets or sets the city of the address.
        /// </summary>
        public string City
        {
            get
            {
                return _city;
            }
            set
            {
                _city = value;
            }
        }

        /// <summary>
        /// Gets or sets the county that the address is in.
        /// </summary>
        public string County
        {
            get
            {
                return _county;
            }
            set
            {
                _county = value;
            }
        }

        /// <summary>
        /// Gets or sets the region of the address.
        /// </summary>
        public virtual string Region
        {
            get
            {
                return _region;
            }
            set
            {
                _region = value;
            }
        }

        /// <summary>
        /// Gets or sets the postal code.
        /// </summary>
        public string PostalCode
        {
            get
            {
                return _postalCode;
            }
            set
            {
                _postalCode = value;
            }
        }

        /// <summary>
        /// Gets or sets the country the address is in
        /// </summary>
        public Country Country
        {
            get
            {
                return _country;
            }
            set
            {
                _country = value;
            }
        }

        /// <summary>
        /// Gets the address as a string.
        /// </summary>
        /// <returns>The string representation of the address.</returns>
        public override string ToString()
        {
            StringBuilder b = new StringBuilder();

            if (Address1 != null && Address1.Length > 0)
                b.Append(Address1);

            if (Apartment != null && Apartment.Length > 0)
                b.AppendFormat(" Apt. {0}\r\n", Apartment);
            else
                b.AppendLine();

            if (Address2 != null && Address2.Length > 0)
                b.AppendLine(Address2);

            if (City != null)
                b.AppendFormat("{0},", City);

            if (Region != null)
                b.AppendFormat(" {0}", Region);

            if (PostalCode != null)
                b.AppendFormat(" {0}", PostalCode);

            if (Country != Country.Empty)
            {
                b.AppendLine();
                b.Append(Country.ToString());
            }

            return b.ToString();
        }

        #region IXmlSerializable Members

        System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()
        {
            return null;
        }

        void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
        {
            if (reader == null)
                throw new ArgumentNullException("reader");
        
            reader.Read();

            _address1 = reader["address1"];
            _address2 = reader["address2"];
            _apartment = reader["apartment"];
            _city = reader["city"];
            _county = reader["county"];
            _region = reader["region"];
            _postalCode = reader["postalCode"];
            _country = (reader["country"] == null) ? Country.Empty : Country.FromCountryCode(reader["country"]);
        }

        void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
        {
            if (writer == null)
                throw new ArgumentNullException("writer");
        

            writer.WriteStartElement("address");

            if (_address1 != null)
                writer.WriteAttributeString("address1", _address1);
            
            if (_address2 != null)
                writer.WriteAttributeString("address2", _address2);

            if (_apartment != null)
                writer.WriteAttributeString("apartment", _apartment);

            if (_city != null)
                writer.WriteAttributeString("city", _city);
            
            if (_county != null)
                writer.WriteAttributeString("county", _county);
            
            if (_region != null)
                writer.WriteAttributeString("region", _region);
    
            if (_postalCode != null)
                writer.WriteAttributeString("postalCode", _postalCode);
            
            if (_country != Country.Empty)
                writer.WriteAttributeString("countryCode", _country.ToString());

            writer.WriteEndElement(); // address
        }

        #endregion
    }
}
